#include <iostream>
#include <Windows.h>
#include <Psapi.h>
using namespace std;

int main()
{
	DWORD processId = 13468;
    std::cout << "请输入目标进程的PID: \n";
    //std::cin >> processId;

    // 获取 DLL 的完整路径
    char dllPath[MAX_PATH];
	const char* path = "d:\\dllInject.dll";
    GetFullPathNameA(path, MAX_PATH, dllPath, NULL);

    // 获取目标进程句柄
    HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
    if (processHandle == NULL)
    {
        std::cerr << "无法打开目标进程" << std::endl;
        return 1;
    }

	// 获取目标进程中已加载的模块列表
	HMODULE hModules[1024];
	DWORD cbNeeded;
	EnumProcessModules(processHandle, hModules, sizeof(hModules), &cbNeeded);

	// 卸载之前注入的 DLL
	for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
	{
		DWORD d=GetModuleFileNameExA(processHandle, hModules[i], dllPath, sizeof(dllPath));
		if (d)
		{
			if (_stricmp(dllPath, path) == 0)
			{
				// 卸载 DLL
				HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, hModules[i], 0, NULL);
				WaitForSingleObject(remoteThread, INFINITE);
				CloseHandle(remoteThread);
				break;
			}
		}
	}

    // 在目标进程中加载 DLL
    LPVOID remoteMemory = VirtualAllocEx(processHandle, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	cout << "remoteMemory " << remoteMemory << endl;
    BOOL s=WriteProcessMemory(processHandle, remoteMemory, dllPath, MAX_PATH, NULL);
	cout << "WriteProcessMemory " << s << endl;
    HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, remoteMemory, 0, NULL);

    if (remoteThread == NULL)
    {
        std::cerr << "失败" << std::endl;
        CloseHandle(processHandle);
        return 1;
    }

    std::cout << "成功" << std::endl;

	// 等待注入线程退出
	WaitForSingleObject(remoteThread, INFINITE);

    // 清理资源
    CloseHandle(remoteThread);
    VirtualFreeEx(processHandle, remoteMemory, 0, MEM_RELEASE);
    CloseHandle(processHandle);

	/*
	HANDLE exitRemoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, remoteMemory, 0, NULL);
	WaitForSingleObject(exitRemoteThread, INFINITE);
	CloseHandle(exitRemoteThread);
	*/
    return 0;
}
